#
# Copyright 2010 Steve Leach
# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#

import unittest
import logging

from datetime import datetime, date, timedelta
from operator import attrgetter


from handlers import EveOpsHandler

from evedata import EveData, get_eve_data
from eveoperation import EveOperation, Pilot
from formatting import format_thousands

class Stats:
	total_ops = 0
	deleted_ops = 0
	paid_ops = 0
	total_isk = 0
	total_members = 0
	date_first = datetime.now()
	date_last = datetime(1900,01,01)

class StatsVal:
	ops = 0
	isk = 0

	def isk_000(self):
		return format_thousands(self.isk)

	def average(self):
		if self.ops == 0:
			return 0
		return self.isk / self.ops

	def ave_000(self):
		return format_thousands(self.average())

def calc_stats(ops, pilot):
	stats = Stats()

	stats.system_map = {}
	stats.pilot_map = {}
	stats.fc_list = []

	today = date.today()
	one_week = timedelta(days=7)
	last_week = today - one_week

	stats.last_week_ops = 0
	stats.last_week_isk = 0

	stats.daily = [0,0,0,0,0,0,0]
	for d in range(7):
		stats.daily[d] = StatsVal()

	stats.daily[0].day = 'Mon'
	stats.daily[1].day = 'Tue'
	stats.daily[2].day = 'Wed'
	stats.daily[3].day = 'Thu'
	stats.daily[4].day = 'Fri'
	stats.daily[5].day = 'Sat'
	stats.daily[6].day = 'Sun'

	stats.hourly = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
	for h in range(24):
		stats.hourly[h] = StatsVal()
		stats.hourly[h].hour = h

	stats.site_map = {}
	stats.month_map = {}

	stats.my_ops = 0
	stats.my_isk = 0

	for op in ops:
		stats.total_ops += 1
		if op.paid:
			stats.paid_ops += 1
		if op.deleted_op:
			stats.deleted_ops += 1
		stats.total_isk += op.isk
		stats.total_members += len(op.pilots)

		if pilot in op.pilots:
			stats.my_ops += 1
			stats.my_isk += (op.isk * 0.9) / len(op.pilots)

		if op.fc:
			stats.fc_list.append(op.fc)

		if op.system:
			if op.system not in stats.system_map:
				stats.system_map[op.system] = StatsVal()
				stats.system_map[op.system].name = op.system
			stats.system_map[op.system].ops += 1
			stats.system_map[op.system].isk += op.isk

		if op.op_time:
			dow = op.op_time.weekday()
			stats.daily[dow].ops += 1
			stats.daily[dow].isk += op.isk

			hour = op.op_time.hour
			stats.hourly[hour].ops += 1
			stats.hourly[hour].isk += op.isk

			if op.op_time < stats.date_first:
				stats.date_first = op.op_time
			if op.op_time > stats.date_last:
				stats.date_last = op.op_time

			if op.op_time.date() >= last_week:
				stats.last_week_ops += 1
				stats.last_week_isk += op.isk

			month_str = op.op_time.strftime('%Y-%m')			
			if not month_str in stats.month_map:
				m = StatsVal()
				m.name = month_str
				m.ops = 0
				m.isk = 0
				m.isk_000 = '0'		
				stats.month_map[month_str] = m
			month = stats.month_map[month_str]
			month.ops += 1
			month.isk += op.isk
			month.isk_000 = format_thousands(month.isk)

		if op.site_type:
			if op.site_type not in stats.site_map:
				stats.site_map[op.site_type] = StatsVal()
				stats.site_map[op.site_type].site_name = op.site_type
			stats.site_map[op.site_type].ops += 1
			stats.site_map[op.site_type].isk += op.isk

	stats.fc_list = set(stats.fc_list)	# remove duplicates
	stats.fc_count = len(stats.fc_list)

	stats.total_isk_000 = format_thousands(stats.total_isk)
	stats.last_week_isk_000 = format_thousands(stats.last_week_isk)

	stats.ave_members = 1.0 * stats.total_members / stats.total_ops
	stats.ave_isk = stats.total_isk / stats.total_ops
	stats.ave_isk_000 = format_thousands(int(stats.ave_isk))
	stats.ave_pilot_isk_000 = format_thousands(int(stats.total_isk / stats.total_members))

	stats.my_isk_000 = format_thousands(int(stats.my_isk))

	stats.systems = []
	stats.pilots = []

	stats.systems = stats.system_map.values()

	stats.elapsed_days = (stats.date_last.date() - stats.date_first.date()).days

	if stats.elapsed_days > 0:
		stats.corp_isk_per_day  = stats.total_isk / stats.elapsed_days
		stats.ops_per_day = 1.0 * stats.total_ops / stats.elapsed_days
	else:
		stats.corp_isk_per_day = 0
		stats.ops_per_day = 0

	stats.corp_isk_per_day_000  = format_thousands(int(stats.corp_isk_per_day))

	stats.month_list = sorted(stats.month_map.values(), key=attrgetter('name'), reverse=True)

	return stats

class StatsHandler(EveOpsHandler):
	def get(self):  
		logging.info('Stats handler invoked')

		eve_data = get_eve_data(self.request.headers)

		if not self.authorised(eve_data):
			return

		ops = EveOperation.gql('WHERE deleted_op = False')
		stats = calc_stats(ops, eve_data.char_name)

		values = {'stats': stats, 'eve_data': eve_data, 'headers': self.request.headers}

		self.display_page( 'stats.html', values )

    
